package cn.net.xyan.easy.webapp.base.utils;


import cn.net.xyan.easy.spring.core.utils.StringUtils;
import cn.net.xyan.easy.webapp.base.annotation.Module;
import cn.net.xyan.easy.webapp.base.entity.WebModule;
import cn.net.xyan.easy.webapp.base.service.IWebModuleService;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.lang.reflect.Method;

/**
 * Created by xiashenpin on 16/2/9.
 */
@Order(value = 9999)
public class WebModuleFinder implements BeanPostProcessor {


    @Autowired
    IWebModuleService moduleService;


    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        Class<?> beanClass = bean.getClass();

        //find module
        if (beanClass.isAnnotationPresent(Controller.class)
                && beanClass.isAnnotationPresent(RequestMapping.class)
                && beanClass.isAnnotationPresent(Module.class)){
            RequestMapping requestMapping = beanClass.getAnnotation(RequestMapping.class);
            Module module = beanClass.getAnnotation(Module.class);
            if (requestMapping.value().length >0) {
                String moduleName = beanClass.getCanonicalName();
                String baseURL = requestMapping.value()[0];
                WebModule webModule = moduleService.setupModule(null,moduleName, baseURL, module);

                for (Method method : beanClass.getDeclaredMethods()){
                    if (method.isAnnotationPresent(RequestMapping.class) && method.isAnnotationPresent(Module.class)){
                        RequestMapping itemRequestMapping = method.getAnnotation(RequestMapping.class);
                        Module itemModule = method.getAnnotation(Module.class);
                        String itemName = String.format("%s.%s",moduleName,method.getName());
                        if (itemRequestMapping.value().length>0){
                            moduleService.setupModule(webModule,itemName,itemRequestMapping.value()[0],itemModule);
                        }
                    }
                }
            }

        }


        //find rest service
        if (beanClass.isAnnotationPresent(Controller.class)
                && beanClass.isAnnotationPresent(RequestMapping.class)
               ){
            RequestMapping requestMapping = beanClass.getAnnotation(RequestMapping.class);
            if (requestMapping.value().length >0) {

                String baseURL = requestMapping.value()[0];
                if ("/".equals(baseURL))
                    baseURL = "";
                for (Method method : beanClass.getDeclaredMethods()) {
                    if (method.isAnnotationPresent(RequestMapping.class) && method.isAnnotationPresent(ResponseBody.class)) {
                        RequestMapping itemRequestMapping = method.getAnnotation(RequestMapping.class);
                        String serviceName = StringUtils.upperCaseFirst(method.getName());

                        if (itemRequestMapping.value().length > 0) {
                            String url = itemRequestMapping.value()[0];
                            moduleService.setupRestService(baseURL,serviceName,url);
                        }
                    }
                }

            }
        }



        return bean;
    }
}
